package com.zkh.myframe.database.mapper.parser;

import java.util.HashMap;

import com.zkh.myframe.database.mapper.MapperEntity;
import com.zkh.myframe.database.mapper.MapperParseException;
import com.zkh.myframe.database.mapper.SQLEntity;
import com.zkh.myframe.database.mapper.tag.Include;
import com.zkh.myutils.markup.Element;
import com.zkh.myutils.utils.StringUtils;

/**
 * Include解析器
 * @author zkh
 */
public class IncludeParser {
	
	/**
	 * 解析主方法
	 * @param node Include标签节点
	 * @param namespace 命名空间
	 */
	public static Include parse(Element node, String namespace) {
		//初始化对象
		Include include = new Include();
		//获取ID
		String refid = node.getAttr("refid");
		//为空
		if(StringUtils.isEmpty(refid)) {
			throw new MapperParseException("include标签refid值不能为空");
		}
		//是否存在点
		int index = refid.lastIndexOf(".");
		//格式
		if(index==0 || index==refid.length()-1) {
			throw new MapperParseException("include标签refid值不能以点开始或结尾");
		}
		//命名空间
		String ns = index==-1 ? namespace : refid.substring(0, index);
		//ID
		String id = index==-1 ? refid : refid.substring(index+1);
		//获取已存在的SQL对象
		SQLEntity entity = MapperEntity.getGlobalSQLEntity(ns, id);
		//不存在
		if(StringUtils.isEmpty(entity.getNamespace())) {
			//如果已经在未处理集中，则直接取用
			SQLEntity temp = Parser.unDealSQLMap.getOrDefault(ns, new HashMap<>()).get(id);
			//已经有，直接保存
			if(temp!=null) {
				entity = temp;
			}else {
				//初始化一个对象
				entity = new SQLEntity(ns, id);
				//保存未处理结果集
				Parser.putUnDealSQL(ns, id, entity);
			}
		}
		//保存
		include.setSqlEntity(entity);
		//解析下面的param标签
		parseParam(node, include);
		//返回
		return include;
	}

	/**
	 * 解析param标签
	 */
	private static void parseParam(Element pnode, Include include) {
		//遍历
		pnode.getChildren().forEach(node->{
			//只处理param标签
			if("param".equalsIgnoreCase(node.getName())) {
				//属性值
				String name = node.getAttr("name");
				String value = node.getAttr("value", true);
				//key为空
				if(StringUtils.isEmpty(name)) {
					throw new MapperParseException("param标签name属性值不能为空");
				}
				//保存
				include.putParam(name, ParamValue.parseValue(value));
			}
		});
	}
}
